﻿namespace Quail
{
    /// <summary>
    /// Default interface for all test shells
    /// </summary>
    public abstract class SeleniumTestShell<TBrowser, TPage> : TestShell<TBrowser, TPage>
        where TBrowser : IWebBrowser
        where TPage : IWebPage
    {
        /// <summary>
        /// Initializes a new instance of the SAJTestShell class.
        /// </summary>
        /// <param name="testname">Name of the test</param>
        /// <param name="owninginstance">The object that is creating the SAJTestShell (for logging purposes)</param>
        protected SeleniumTestShell(string testname, object owninginstance)
            : this(testname, BrowserTypes.FireFox, owninginstance)
        {
        }

        protected SeleniumTestShell(string testname, BrowserTypes browser, object owninginstance)
            :base(testname, owninginstance)
        {
            DefaultBrowserType = browser;
        }

        /// <summary>
        /// Gets or sets the default browser to use for the test (default: BrowserTypes.FireFox)
        /// </summary>
        public BrowserTypes DefaultBrowserType
        {
            get; set;
        }

        /// <summary>
        /// Gets the TestSession as a SeleniumTestSession object
        /// </summary>
        public SeleniumTestSession SeleniumTestSession
        {
            get { return TestSession as SeleniumTestSession; }
        }

        /// <summary>
        /// Attaches to an existing selenium session.
        /// </summary>
        /// <param name="sessionid">The sessionid.</param>
        public void AttachToSession(string sessionid)
        {
            AttachToSession(SeleniumTestSession.RcHost, sessionid);
        }

        /// <summary>
        /// Attaches to an existing selenium session.
        /// </summary>
        /// <param name="host">The remote control host.</param>
        /// <param name="sessionid">The sessionid.</param>
        public void AttachToSession(RemoteControlHost host, string sessionid)
        {
            SeleniumTestSession.RcHost = host;

            if (SeleniumTestSession.RootTask == null)
            {
                SeleniumTestSession.StartLogger(null);

                // add the factories
                AddLoggerFactories();
            }

            SeleniumTestSession.Attach(sessionid);
        }

        /// <summary>
        /// Creates a new test session instance
        /// </summary>
        /// <returns>A new test session</returns>
        protected override TestSession CreateNewTestSession()
        {
            return new SeleniumTestSession(TestName)
                       {
                           BrowserType = DefaultBrowserType
                       };
        }

        protected override void PreStartTestSession(TestSession session)
        {
            base.PreStartTestSession(session);

            session.ActiveTask.AddLog(LogStatus.Information, "Selenium RC: " + ((SeleniumTestSession)session).RcHost);
        }

        protected override void PostStartTestSession(TestSession session)
        {
            base.PostStartTestSession(session);

            if (session.Browser is WebBrowser)
                ((WebBrowser)session.Browser).LogLevel = WebBrowser.SeleniumLogLevel.off;
        }

        /// <summary>
        /// Closes a window on the remote host
        /// </summary>
        /// <param name="windowName">The window name to close</param>
        /// <param name="delay">how long to delay before closing it</param>
        public void CloseWindow(string windowName, int delay)
        {
            SeleniumTestSession.CloseWindow(windowName, delay);
        }
    }
}
